home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / Interfaces&Libraries / Universal / Interfaces / PInterfaces / PEFBinaryFormat.p < prev    next >
Encoding:
Text File  |  1998-02-12  |  37.6 KB  |  803 lines  |  [TEXT/MPS ]

  1. {
  2.      File:        PEFBinaryFormat.p
  3.  
  4.      Contains:    PEF Types and Macros
  5.  
  6.      Version:    Technology:    Master Interfaces
  7.                  Release:    Universal Interfaces 3.1
  8.  
  9.      Copyright:    © 1993-1998, 1998 by Apple Computer, Inc., all rights reserved.
  10.  
  11.      Bugs?:        Please include the the file and version information (from above) with
  12.                  the problem description.  Developers belonging to one of the Apple
  13.                  developer programs can submit bug reports to:
  14.  
  15.                      devsupport@apple.com
  16.  
  17. }
  18.  
  19.  
  20. {$IFC UNDEFINED UsingIncludes}
  21. {$SETC UsingIncludes := 0}
  22. {$ENDC}
  23.  
  24. {$IFC NOT UsingIncludes}
  25.  UNIT PEFBinaryFormat;
  26.  INTERFACE
  27. {$ENDC}
  28.  
  29. {$IFC UNDEFINED __PEFBINARYFORMAT__}
  30. {$SETC __PEFBINARYFORMAT__ := 1}
  31.  
  32. {$I+}
  33. {$SETC PEFBinaryFormatIncludes := UsingIncludes}
  34. {$SETC UsingIncludes := 1}
  35.  
  36. {$IFC UNDEFINED __MACTYPES__}
  37. {$I MacTypes.p}
  38. {$ENDC}
  39.  
  40.  
  41. {$PUSH}
  42. {$ALIGN MAC68K}
  43. {$LibExport+}
  44.  
  45.  
  46. { -----------------------------------------------------------------------------------------    }
  47. { Almost all types are padded for natural alignment.  However the PEFExportedSymbol type is    }
  48. { 10 bytes long, containing two 32 bit fields and one 16 bit field.  Arrays of it must be        }
  49. { packed, so it requires "68K" alignment.  Setting this globally to 68K should also help        }
  50. { ensure consistent treatment across compilers.                                                }
  51.  
  52. { ======================================================================================== }
  53. { Overall Structure }
  54. { ================= }
  55.  
  56. { -------------------------------------------------------------------------------------------    }
  57. { This header contains a complete set of types and macros for dealing with the PEF executable    }
  58. { format.  While some description is provided, this header is not meant as a primary source    }
  59. { of documentation on PEF.  An excellent specification of PEF can be found in the Macintosh    }
  60. { Runtime Architectures book.  This header is primarily a physical format description.  Thus    }
  61. { it depends on as few other headers as possible and structure fields have obvious sizes.        }
  62. {                                                                                                 }
  63. { The physical storage for a PEF executable is known as a "container".  This refers to just    }
  64. { the executable itself, not the file etc.  E.g. if five DLLs are packaged in a single file's    }
  65. { data fork, that one data fork has five containers within it.                                    }
  66. {                                                                                                 }
  67. { A PEF container consists of an overall header, followed by one or more section headers,        }
  68. { followed by the section name table, followed by the contents for the sections.  Some kinds    }
  69. { of sections have specific internal representation.  The "loader" section is the most common    }
  70. { of these special sections.  It contains information on the exports, imports, and runtime        }
  71. { relocations required to prepare the executable.  PEF containers are self contained, all        }
  72. { portions are located via relative offsets.                                                    }
  73. {                                                                                                 }
  74. {                                                                                                 }
  75. {            +-------------------------------+                                                    }
  76. {            |        Container Header        |    40 bytes                                        }
  77. {            +-------------------------------+                                                    }
  78. {            |        Section 0 header        |    28 bytes each                                    }
  79. {            |...............................|                                                    }
  80. {            |            - - - -                |                                                    }
  81. {            |...............................|                                                    }
  82. {            |        Section n-1 header        |                                                    }
  83. {            +-------------------------------+                                                    }
  84. {            |        Section Name Table        |                                                    }
  85. {            +-------------------------------+                                                    }
  86. {            |        Section x raw data        |                                                    }
  87. {            +-------------------------------+                                                    }
  88. {             |            - - - -                |                                                    }
  89. {            +-------------------------------+                                                    }
  90. {            |        Section y raw data        |                                                    }
  91. {            +-------------------------------+                                                    }
  92. {                                                                                                 }
  93. {                                                                                                 }
  94. { The sections are implicitly numbered from 0 to n according to the order of their headers.    }
  95. { The headers of the instantiated sections must precede those of the non-instantiated            }
  96. { sections.  The ordering of the raw data is independent of the section header ordering.        }
  97. { Each section header contains the offset for that section's raw data.                            }
  98.  
  99. { =========================================================================================== }
  100. { Container Header }
  101. { ================ }
  102.  
  103.  
  104. TYPE
  105.     PEFContainerHeaderPtr = ^PEFContainerHeader;
  106.     PEFContainerHeader = RECORD
  107.         tag1:                    OSType;                                    {  Must contain 'Joy!'.  }
  108.         tag2:                    OSType;                                    {  Must contain 'peff'.  (Yes, with two 'f's.)  }
  109.         architecture:            OSType;                                    {  The ISA for code sections.  Constants in CodeFragments.h.  }
  110.         formatVersion:            UInt32;                                    {  The physical format version.  }
  111.         dateTimeStamp:            UInt32;                                    {  Macintosh format creation/modification stamp.  }
  112.         oldDefVersion:            UInt32;                                    {  Old definition version number for the code fragment.  }
  113.         oldImpVersion:            UInt32;                                    {  Old implementation version number for the code fragment.  }
  114.         currentVersion:            UInt32;                                    {  Current version number for the code fragment.  }
  115.         sectionCount:            UInt16;                                    {  Total number of section headers that follow.  }
  116.         instSectionCount:        UInt16;                                    {  Number of instantiated sections.  }
  117.         reservedA:                UInt32;                                    {  Reserved, must be written as zero.  }
  118.     END;
  119.  
  120.  
  121. CONST
  122.     kPEFTag1                    = 'Joy!';                        {  For non-Apple compilers: 0x4A6F7921.  }
  123.     kPEFTag2                    = 'peff';                        {  For non-Apple compilers: 0x70656666.  }
  124.     kPEFVersion                    = $00000001;
  125.  
  126.  
  127.     kPEFFirstSectionHeaderOffset = 40;
  128.  
  129.  
  130. { =========================================================================================== }
  131. { Section Headers }
  132. { =============== }
  133.  
  134.  
  135. TYPE
  136.     PEFSectionHeaderPtr = ^PEFSectionHeader;
  137.     PEFSectionHeader = RECORD
  138.         nameOffset:                SInt32;                                    {  Offset of name within the section name table, -1 => none.  }
  139.         defaultAddress:            UInt32;                                    {  Default address, affects relocations.  }
  140.         totalLength:            UInt32;                                    {  Fully expanded size in bytes of the section contents.  }
  141.         unpackedLength:            UInt32;                                    {  Size in bytes of the "initialized" part of the contents.  }
  142.         containerLength:        UInt32;                                    {  Size in bytes of the raw data in the container.  }
  143.         containerOffset:        UInt32;                                    {  Offset of section's raw data.  }
  144.         sectionKind:            SInt8;                                    {  Kind of section contents/usage.  }
  145.         shareKind:                SInt8;                                    {  Sharing level, if a writeable section.  }
  146.         alignment:                SInt8;                                    {  Preferred alignment, expressed as log 2.  }
  147.         reservedA:                SInt8;                                    {  Reserved, must be zero.  }
  148.     END;
  149.  
  150.  
  151. CONST
  152.                                                                 {  Values for the sectionKind field.  }
  153.                                                                 {     Section kind values for instantiated sections.  }
  154.     kPEFCodeSection                = 0;                            {  Code, presumed pure & position independent.  }
  155.     kPEFUnpackedDataSection        = 1;                            {  Unpacked writeable data.  }
  156.     kPEFPackedDataSection        = 2;                            {  Packed writeable data.  }
  157.     kPEFConstantSection            = 3;                            {  Read-only data.  }
  158.     kPEFExecDataSection            = 6;                            {  Intermixed code and writeable data.  }
  159.                                                                 {  Section kind values for non-instantiated sections.  }
  160.     kPEFLoaderSection            = 4;                            {  Loader tables.  }
  161.     kPEFDebugSection            = 5;                            {  Reserved for future use.  }
  162.     kPEFExceptionSection        = 7;                            {  Reserved for future use.  }
  163.     kPEFTracebackSection        = 8;                            {  Reserved for future use.  }
  164.  
  165.  
  166.                                                                 {  Values for the shareKind field.  }
  167.     kPEFProcessShare            = 1;                            {  Shared within a single process.  }
  168.     kPEFGlobalShare                = 4;                            {  Shared across the entire system.  }
  169.     kPEFProtectedShare            = 5;                            {  Readable across the entire system, writeable only to privileged code.  }
  170.  
  171.  
  172. { =========================================================================================== }
  173. { Packed Data Contents }
  174. { ==================== }
  175.  
  176. { -------------------------------------------------------------------------------------------    }
  177. { The raw contents of a packed data section are a sequence of byte codes.  The basic format    }
  178. { has a 3 bit opcode followed by a 5 bit count.  Additional bytes might be used to contain        }
  179. { counts larger than 31, and to contain a second or third count.  Further additional bytes        }
  180. { contain actual data values to transfer.                                                        }
  181. {                                                                                                 }
  182. { All counts are represented in a variable length manner.  A zero in the initial 5 bit count    }
  183. { indicates the actual value follows.  In this case, and for the second and third counts, the    }
  184. { count is represented as a variable length sequence of bytes.  The bytes are stored in big    }
  185. { endian manner, most significant part first.  The high order bit is set in all but the last    }
  186. { byte.  The value is accumulated by shifting the current value up 7 bits and adding in the    }
  187. { low order 7 bits of the next byte.                                                            }
  188.  
  189.                                                                 {  The packed data opcodes.  }
  190.     kPEFPkDataZero                = 0;                            {  Zero fill "count" bytes.  }
  191.     kPEFPkDataBlock                = 1;                            {  Block copy "count" bytes.  }
  192.     kPEFPkDataRepeat            = 2;                            {  Repeat "count" bytes "count2"+1 times.  }
  193.     kPEFPkDataRepeatBlock        = 3;                            {  Interleaved repeated and unique data.  }
  194.     kPEFPkDataRepeatZero        = 4;                            {  Interleaved zero and unique data.  }
  195.  
  196.  
  197.     kPEFPkDataOpcodeShift        = 5;
  198.     kPEFPkDataCount5Mask        = $1F;
  199.     kPEFPkDataMaxCount5            = 31;
  200.     kPEFPkDataVCountShift        = 7;
  201.     kPEFPkDataVCountMask        = $7F;
  202.     kPEFPkDataVCountEndMask        = $80;
  203.  
  204.  
  205.  
  206. { ------------------------------------------------------------------------------------------    }
  207. { The following code snippet can be used to input a variable length count.                        }
  208. {                                                                                                 }
  209. {        count = 0;                                                                                }
  210. {        do (                                                                                    }
  211. {            byte = *bytePtr++;                                                                    }
  212. {            count = (count << kPEFPkDataVCountShift) | (byte & kPEFPkDataVCountMask);            }
  213. {        ) while ( (byte & kPEFPkDataVCountEndMask) != 0 );                                        }
  214. {                                                                                                 }
  215. { The following code snippet can be used to output a variable length count to a byte array.    }
  216. { This is more complex than the input code because the chunks are output in big endian order.    }
  217. { Think about handling values like 0 or 0x030000.                                                }
  218. {                                                                                                 }
  219. {        count = 1;.                                                                                }
  220. {        tempValue = value >> kPEFPkDataCountShift;                                                }
  221. {        while ( tempValue != 0 ) (                                                                }
  222. {            count += 1;                                                                            }
  223. {            tempValue = tempValue >> kPEFPkDataCountShift;                                        }
  224. {        )                                                                                        }
  225. {                                                                                                 }
  226. {        bytePtr += count;                                                                        }
  227. {        tempPtr = bytePtr - 1;                                                                    }
  228. {        *tempPtr-- = value;        // ! No need to mask, only the low order byte is stored.        }
  229. {        for ( count -= 1; count != 0; count -= 1 ) (                                            }
  230. {            value = value >> kPEFPkDataCountShift;                                                }
  231. {            *tempPtr-- = value | kPEFPkDataCountEndMask;                                        }
  232. {        )                                                                                        }
  233.  
  234. { =========================================================================================== }
  235. { Loader Section }
  236. { ============== }
  237.  
  238. { ------------------------------------------------------------------------------------------    }
  239. { The loader section contains information needed to prepare the code fragment for execution.    }
  240. { This includes this fragment's exports, the import libraries and the imported symbols from    }
  241. { each library, and the relocations for the writeable sections.                                }
  242. {                                                                                                 }
  243. {            +-----------------------------------+                <-- containerOffset --------+    }
  244. {            |        Loader Info Header            |    56 bytes                                |    }
  245. {            |-----------------------------------|                                            |    }
  246. {            |        Imported Library 0            |    24 bytes each                            |    }
  247. {            |...................................|                                            |    }
  248. {            |            - - -                    |                                            |    }
  249. {            |...................................|                                            |    }
  250. {            |        Imported Library l-1        |                                            |    }
  251. {            |-----------------------------------|                                            |    }
  252. {            |        Imported Symbol 0            |    4 bytes each                            |    }
  253. {            |...................................|                                            |    }
  254. {            |            - - -                    |                                            |    }
  255. {            |...................................|                                            |    }
  256. {            |         Imported Symbol i-1            |                                            |    }
  257. {            |-----------------------------------|                                            |    }
  258. {            |        Relocation Header 0            |    12 bytes each                            |    }
  259. {            |...................................|                                            |    }
  260. {            |            - - -                    |                                            |    }
  261. {            |...................................|                                            |    }
  262. {            |        Relocation Header r-1        |                                            |    }
  263. {            |-----------------------------------|                <-- + relocInstrOffset -----|    }
  264. {            |        Relocation Instructions        |                                            |    }
  265. {            |-----------------------------------|                <-- + loaderStringsOffset --|    }
  266. {            |        Loader String Table            |                                            |    }
  267. {            |-----------------------------------|                <-- + exportHashOffset -----+    }
  268. {            |        Export Hash Slot 0            |    4 bytes each                                }
  269. {            |...................................|                                                }
  270. {            |            - - -                    |                                                }
  271. {            |...................................|                                                }
  272. {            |         Export Hash Slot h-1        |                                                }
  273. {            |-----------------------------------|                                                }
  274. {            |        Export Symbol Key 0            |    4 bytes each                                }
  275. {            |...................................|                                                }
  276. {            |            - - -                    |                                                }
  277. {            |...................................|                                                }
  278. {            |        Export Symbol Key e-1        |                                                }
  279. {            |-----------------------------------|                                                }
  280. {            |        Export Symbol 0                |    10 bytes each                                }
  281. {            |...................................|                                                }
  282. {            |            - - -                    |                                                }
  283. {            |...................................|                                                }
  284. {            |        Export Symbol e-1            |                                                }
  285. {            +-----------------------------------+                                                }
  286.  
  287.  
  288. TYPE
  289.     PEFLoaderInfoHeaderPtr = ^PEFLoaderInfoHeader;
  290.     PEFLoaderInfoHeader = RECORD
  291.         mainSection:            SInt32;                                    {  Section containing the main symbol, -1 => none.  }
  292.         mainOffset:                UInt32;                                    {  Offset of main symbol.  }
  293.         initSection:            SInt32;                                    {  Section containing the init routine's TVector, -1 => none.  }
  294.         initOffset:                UInt32;                                    {  Offset of the init routine's TVector.  }
  295.         termSection:            SInt32;                                    {  Section containing the term routine's TVector, -1 => none.  }
  296.         termOffset:                UInt32;                                    {  Offset of the term routine's TVector.  }
  297.         importedLibraryCount:    UInt32;                                    {  Number of imported libraries.  ('l')  }
  298.         totalImportedSymbolCount: UInt32;                                {  Total number of imported symbols.  ('i')  }
  299.         relocSectionCount:        UInt32;                                    {  Number of sections with relocations.  ('r')  }
  300.         relocInstrOffset:        UInt32;                                    {  Offset of the relocation instructions.  }
  301.         loaderStringsOffset:    UInt32;                                    {  Offset of the loader string table.  }
  302.         exportHashOffset:        UInt32;                                    {  Offset of the export hash table.  }
  303.         exportHashTablePower:    UInt32;                                    {  Export hash table size as log 2.  (Log2('h'))  }
  304.         exportedSymbolCount:    UInt32;                                    {  Number of exported symbols.  ('e')  }
  305.     END;
  306.  
  307. { =========================================================================================== }
  308. { Imported Libraries }
  309. { ------------------ }
  310.     PEFImportedLibraryPtr = ^PEFImportedLibrary;
  311.     PEFImportedLibrary = RECORD
  312.         nameOffset:                UInt32;                                    {  Loader string table offset of library's name.  }
  313.         oldImpVersion:            UInt32;                                    {  Oldest compatible implementation version.  }
  314.         currentVersion:            UInt32;                                    {  Current version at build time.  }
  315.         importedSymbolCount:    UInt32;                                    {  Imported symbol count for this library.  }
  316.         firstImportedSymbol:    UInt32;                                    {  Index of first imported symbol from this library.  }
  317.         options:                SInt8;                                    {  Option bits for this library.  }
  318.         reservedA:                SInt8;                                    {  Reserved, must be zero.  }
  319.         reservedB:                UInt16;                                    {  Reserved, must be zero.  }
  320.     END;
  321.  
  322.  
  323. CONST
  324.                                                                 {  Bits for the PEFImportedLibrary options field.  }
  325.     kPEFWeakImportLibMask        = $40;                            {  The imported library is allowed to be missing.  }
  326.     kPEFInitLibBeforeMask        = $80;                            {  The imported library must be initialized first.  }
  327.  
  328.  
  329. { =========================================================================================== }
  330. { Imported Symbols }
  331. { ---------------- }
  332.  
  333. { -------------------------------------------------------------------------------------------    }
  334. { The PEFImportedSymbol type has the following bit field layout.                                }
  335. {                                                                                                 }
  336. {                                                                       3                        }
  337. {         0             7 8                                             1                        }
  338. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  339. {      | symbol class  | offset of symbol name in loader string table  |                        }
  340. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  341. {        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        }
  342.  
  343.  
  344. TYPE
  345.     PEFImportedSymbolPtr = ^PEFImportedSymbol;
  346.     PEFImportedSymbol = RECORD
  347.         classAndName:            UInt32;
  348.     END;
  349.  
  350.  
  351. CONST
  352.     kPEFImpSymClassShift        = 24;
  353.     kPEFImpSymNameOffsetMask    = $00FFFFFF;
  354.     kPEFImpSymMaxNameOffset        = $00FFFFFF;                    {  16,777,215  }
  355.  
  356.  
  357.                                                                 {  Imported and exported symbol classes.  }
  358.     kPEFCodeSymbol                = $00;
  359.     kPEFDataSymbol                = $01;
  360.     kPEFTVectorSymbol            = $02;
  361.     kPEFTOCSymbol                = $03;
  362.     kPEFGlueSymbol                = $04;
  363.     kPEFUndefinedSymbol            = $0F;
  364.     kPEFWeakImportSymMask        = $80;
  365.  
  366.  
  367. { =========================================================================================== }
  368. { Exported Symbol Hash Table }
  369. { -------------------------- }
  370.  
  371. { -------------------------------------------------------------------------------------------    }
  372. { Exported symbols are described in four parts, optimized for speed of lookup.  These parts    }
  373. { are the "export hash table", the "export key table", the "export symbol table", and the        }
  374. { "export name table".  Overall they contain a flattened representation of a fairly normal        }
  375. { hashed symbol table.                                                                            }
  376. {                                                                                                }
  377. { The export hash table is an array of small fixed size elements.  The number of elements is    }
  378. { a power of 2.  A 32 bit hash word for a symbol is converted into an index into this array.    }
  379. { Each hash slot contains a count of the number of exported symbols that map to this slot and    }
  380. { the index of the first of those symbols in the key and symbol tables.  Of course some hash    }
  381. { slots will have a zero count.                                                                }
  382. {                                                                                                }
  383. { The key and symbol tables are also arrays of fixed size elements, one for each exported        }
  384. { symbol.  Their entries are grouped by hash slot, those elements mapping to the same hash        }
  385. { slot are contiguous.  The key table contains just the full 32 bit hash word for each            }
  386. { exported symbol.  The symbol table contains the offset of the symbol's name in the string    }
  387. { table and other information about the exported symbol.                                        }
  388. {                                                                                                }
  389. { To look up an export you take the hashword and compute the hash slot index.  You then scan    }
  390. { the indicated portion of the key table for matching hashwords.  If a hashword matches, you    }
  391. { look at the corresponding symbol table entry to find the full symbol name.  If the names        }
  392. { match the symbol is found.                                                                    }
  393.  
  394. { -------------------------------------------------------------------------------------------    }
  395. { The following function may be used to compute the hash table size.  Signed values are used    }
  396. { just to avoid potential code generation overhead for unsigned division.                        }
  397. {                                                                                                 }
  398. {        UInt8    PEFComputeHashTableExponent    ( SInt32    exportCount )                            }
  399. {        (                                                                                        }
  400. {            SInt32    exponent;                                                                    }
  401. {                                                                                                 }
  402. {            const SInt32    kExponentLimit        = 16;    // Arbitrary, but must not exceed 30.    }
  403. {            const SInt32    kAverageChainLimit    = 10;    // Arbitrary, for space/time tradeoff.    }
  404. {                                                                                                 }
  405. {            for ( exponent = 0; exponent < kExponentLimit; exponent += 1 ) (                    }
  406. {                if ( (exportCount / (1 << exponent)) < kAverageChainLimit ) break;                }
  407. {            )                                                                                    }
  408. {                                                                                                 }
  409. {            return exponent;                                                                    }
  410. {                                                                                                 }
  411. {        )    // PEFComputeHashTableExponent ()                                                    }
  412.  
  413. { -------------------------------------------------------------------------------------------    }
  414. { The PEFExportedSymbolHashSlot type has the following bit field layout.                        }
  415. {                                                                                                 }
  416. {                                   1 1                                 3                        }
  417. {         0                         3 4                                 1                        }
  418. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  419. {        | symbol count              | index of first export key         |                        }
  420. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  421. {        |<-- 14 bits -------------->|<-- 18 bits ---------------------->|                        }
  422.  
  423.  
  424. TYPE
  425.     PEFExportedSymbolHashSlotPtr = ^PEFExportedSymbolHashSlot;
  426.     PEFExportedSymbolHashSlot = RECORD
  427.         countAndStart:            UInt32;
  428.     END;
  429.  
  430.  
  431. CONST
  432.     kPEFHashSlotSymCountShift    = 18;
  433.     kPEFHashSlotFirstKeyMask    = $0003FFFF;
  434.     kPEFHashSlotMaxSymbolCount    = $00003FFF;                    {   16,383  }
  435.     kPEFHashSlotMaxKeyIndex        = $0003FFFF;                    {  262,143  }
  436.  
  437.  
  438. { =========================================================================================== }
  439. { Exported Symbol Hash Key }
  440. { ------------------------ }
  441.  
  442.  
  443. TYPE
  444.     PEFSplitHashWordPtr = ^PEFSplitHashWord;
  445.     PEFSplitHashWord = RECORD
  446.         nameLength:                UInt16;
  447.         hashValue:                UInt16;
  448.     END;
  449.  
  450.     PEFExportedSymbolKeyPtr = ^PEFExportedSymbolKey;
  451.     PEFExportedSymbolKey = RECORD
  452.         CASE INTEGER OF
  453.         0: (
  454.             fullHashWord:        UInt32;
  455.             );
  456.         1: (
  457.             splitHashWord:        PEFSplitHashWord;
  458.             );
  459.     END;
  460.  
  461.  
  462. CONST
  463.     kPEFHashLengthShift            = 16;
  464.     kPEFHashValueMask            = $0000FFFF;
  465.     kPEFHashMaxLength            = $0000FFFF;                    {  65,535  }
  466.  
  467.  
  468. { -------------------------------------------------------------------------------------------            }
  469. { The following function computes the full 32 bit hash word.                                            }
  470. {                                                                                                         }
  471. {        UInt32    PEFComputeHashWord    ( BytePtr    nameText,        // ! First "letter", not length byte.    }
  472. {                                      UInt32    nameLength )    // ! The text may be zero terminated.    }
  473. {        (                                                                                                }
  474. {            BytePtr    charPtr        = nameText;                                                                }
  475. {            SInt32    hashValue    = 0;        // ! Signed to match old published algorithm.                }
  476. {            UInt32    length        = 0;                                                                    }
  477. {            UInt32    limit;                                                                                }
  478. {            UInt32    result;                                                                                }
  479. {            UInt8    currChar;                                                                            }
  480. {                                                                                                         }
  481. {            #define PseudoRotate(x)  ( ( (x) << 1 ) - ( (x) >> 16 ) )                                    }
  482. {                                                                                                         }
  483. {            for ( limit = nameLength; limit > 0; limit -= 1 ) (                                            }
  484. {                currChar = *charPtr++;                                                                    }
  485. {                if ( currChar == NULL ) break;                                                            }
  486. {                length += 1;                                                                            }
  487. {                hashValue = PseudoRotate ( hashValue ) ^ currChar;                                        }
  488. {            )                                                                                            }
  489. {                                                                                                         }
  490. {            result    = (length << kPEFHashLengthShift) |                                                    }
  491. {                      ((UInt16) ((hashValue ^ (hashValue >> 16)) & kPEFHashValueMask));                    }
  492. {                                                                                                         }
  493. {            return result;                                                                                }
  494. {                                                                                                         }
  495. {        )    // PEFComputeHashWord ()                                                                    }
  496.  
  497. { =========================================================================================== }
  498. { Exported Symbols }
  499. { ---------------- }
  500.  
  501.  
  502. TYPE
  503.     PEFExportedSymbolPtr = ^PEFExportedSymbol;
  504.     PEFExportedSymbol = RECORD
  505.                                                                         {  ! This structure is 10 bytes long and arrays are packed.  }
  506.         classAndName:            UInt32;                                    {  A combination of class and name offset.  }
  507.         symbolValue:            UInt32;                                    {  Typically the symbol's offset within a section.  }
  508.         sectionIndex:            SInt16;                                    {  The index of the section, or pseudo-section, for the symbol.  }
  509.     END;
  510.  
  511. { -------------------------------------------------------------------------------------------    }
  512. { The classAndName field of the PEFExportedSymbol type has the following bit field layout.        }
  513. {                                                                                                 }
  514. {                                                                       3                        }
  515. {         0             7 8                                             1                        }
  516. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  517. {      | symbol class  | offset of symbol name in loader string table  |                        }
  518. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        }
  519. {        |<-- 8 bits --->|<-- 24 bits ---------------------------------->|                        }
  520.  
  521.  
  522. CONST
  523.     kPEFExpSymClassShift        = 24;
  524.     kPEFExpSymNameOffsetMask    = $00FFFFFF;
  525.     kPEFExpSymMaxNameOffset        = $00FFFFFF;                    {  16,777,215  }
  526.  
  527.  
  528.                                                                 {  Negative section indices indicate pseudo-sections.  }
  529.     kPEFAbsoluteExport            = -2;                            {  The symbol value is an absolute address.  }
  530.     kPEFReexportedImport        = -3;                            {  The symbol value is the index of a reexported import.  }
  531.  
  532.  
  533. { =========================================================================================== }
  534. { Loader Relocations }
  535. { ================== }
  536.  
  537. { -------------------------------------------------------------------------------------------    }
  538. { The relocations for a section are defined by a sequence of instructions for an abstract        }
  539. { machine that is specifically geared to performing relocations commonly needed for the "CFM"    }
  540. { code generation model.  These instructions occur in 16 bit chunks.  Most instructions have    }
  541. { just a single chunk.  Instructions that are larger than 16 bits have an opcode and some of    }
  542. { the operands in the first chunk, with other operands in following chunks.                    }
  543.  
  544.  
  545. TYPE
  546.     PEFRelocChunk                        = UInt16;
  547.     PEFLoaderRelocationHeaderPtr = ^PEFLoaderRelocationHeader;
  548.     PEFLoaderRelocationHeader = RECORD
  549.         sectionIndex:            UInt16;                                    {  Index of the section to be fixed up.  }
  550.         reservedA:                UInt16;                                    {  Reserved, must be zero.  }
  551.         relocCount:                UInt32;                                    {  Number of 16 bit relocation chunks.  }
  552.         firstRelocOffset:        UInt32;                                    {  Offset of first relocation instruction.  }
  553.     END;
  554.  
  555. { -------------------------------------------------------------------------------------------    }
  556. { ! Note that the relocCount field is the number of 16 bit relocation chunks, i.e. 1/2 the        }
  557. { ! total number of bytes of relocation instructions.  While most relocation instructions are    }
  558. { ! 16 bits long, some are longer so the number of complete relocation instructions may be        }
  559. { ! less than the relocCount value.                                                            }
  560.  
  561. { ----------------------------------------------------------------------------------    }
  562. { The PEFRelocField macro is a utility for extracting relocation instruction fields.    }
  563.  
  564. { =========================================================================================== }
  565. { Basic Relocation Opcodes }
  566. { ------------------------ }
  567. { ------------------------------------------------------------------------------------------    }
  568. { The number of opcode bits varies from 2 to 7.  The enumeration and switch table given here    }
  569. { are defined in terms of the most significant 7 bits of the first instruction chunk.  An        }
  570. { instruction is decoded by using the most significant 7 bits as an index into the opcode        }
  571. { table, which in turn contains appropriately masked forms of the most significant 7 bits.        }
  572. { The macro PEFRelocBasicOpcode assumes a declaration of the form.                                }
  573. {                                                                                                 }
  574. {        UInt8 kPEFRelocBasicOpcodes [kPEFRelocBasicOpcodeRange] = ( PEFMaskedBasicOpcodes );    }
  575.  
  576.  
  577. CONST
  578.     kPEFRelocBasicOpcodeRange    = 128;
  579.  
  580.  
  581. { -------------------------------------------------------------------------------------------    }
  582. { The relocation opcodes, clustered by major and minor groups.  The instructions within a        }
  583. { cluster all have the same bit field layout.  The enumeration values use the high order 7        }
  584. { bits of the relocation instruction.  Unused low order bits are set to zero.                    }
  585.     kPEFRelocBySectDWithSkip    = $00;                            {  Binary: 00x_xxxx  }
  586.     kPEFRelocBySectC            = $20;                            {  Binary: 010_0000, group is "RelocRun"  }
  587.     kPEFRelocBySectD            = $21;                            {  Binary: 010_0001  }
  588.     kPEFRelocTVector12            = $22;                            {  Binary: 010_0010  }
  589.     kPEFRelocTVector8            = $23;                            {  Binary: 010_0011  }
  590.     kPEFRelocVTable8            = $24;                            {  Binary: 010_0100  }
  591.     kPEFRelocImportRun            = $25;                            {  Binary: 010_0101  }
  592.     kPEFRelocSmByImport            = $30;                            {  Binary: 011_0000, group is "RelocSmIndex"  }
  593.     kPEFRelocSmSetSectC            = $31;                            {  Binary: 011_0001  }
  594.     kPEFRelocSmSetSectD            = $32;                            {  Binary: 011_0010  }
  595.     kPEFRelocSmBySection        = $33;                            {  Binary: 011_0011  }
  596.     kPEFRelocIncrPosition        = $40;                            {  Binary: 100_0xxx  }
  597.     kPEFRelocSmRepeat            = $48;                            {  Binary: 100_1xxx  }
  598.     kPEFRelocSetPosition        = $50;                            {  Binary: 101_000x  }
  599.     kPEFRelocLgByImport            = $52;                            {  Binary: 101_001x  }
  600.     kPEFRelocLgRepeat            = $58;                            {  Binary: 101_100x  }
  601.     kPEFRelocLgSetOrBySection    = $5A;                            {  Binary: 101_101x  }
  602.     kPEFRelocUndefinedOpcode    = $FF;                            {  Used in masking table for all undefined values.  }
  603.  
  604.  
  605. { ----------------------------------------------------------------------------    }
  606. { The RelocLgSetOrBySection instruction has an additional 4 bits of subopcode.    }
  607.     kPEFRelocLgBySectionSubopcode = $00;                        {  Binary: 0000  }
  608.     kPEFRelocLgSetSectCSubopcode = $01;                            {  Binary: 0001  }
  609.     kPEFRelocLgSetSectDSubopcode = $02;                            {  Binary: 0010  }
  610.  
  611.  
  612. { ------------------------------------------------------------------------------------------    }
  613. { The initial values for the opcode "masking" table.  This has the enumeration values from        }
  614. { above with appropriate replications for "don't care" bits.  It is almost certainly shorter    }
  615. { and faster to look up the masked value in a table than to use a branch tree.                    }
  616.  
  617. { =========================================================================================== }
  618. { RelocBySectDWithSkip Instruction }
  619. { -------------------------------- }
  620.  
  621. { -------------------------------------------------------------------------------------------    }
  622. { The "RelocBySectDWithSkip" instruction has the following bit field layout.                    }
  623. {                                                                                                 }
  624. {                             1         1                                                        }
  625. {         0 1 2             9 0         5                                                        }
  626. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  627. {        |0 0| skip count    | rel count |                                                        }
  628. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  629. {        | 2 |<-- 8 bits --->|<--  6 --->|                                                        }
  630. {                                                                                                 }
  631. { ! Note that the stored skip count and reloc count are the actual values!                        }
  632.     kPEFRelocWithSkipMaxSkipCount = 255;
  633.     kPEFRelocWithSkipMaxRelocCount = 63;
  634.  
  635.  
  636. { =========================================================================================== }
  637. { RelocRun Group }
  638. { -------------- }
  639.  
  640. { -------------------------------------------------------------------------------------------    }
  641. { The "RelocRun" group includes the "RelocBySectC", "RelocBySectD", "RelocTVector12",            }
  642. { "RelocTVector8", "RelocVTable8", and "RelocImportRun" instructions.  This group has the        }
  643. { following bit field layout.                                                                    }
  644. {                                                                                                 }
  645. {                                       1                                                        }
  646. {         0   2 3     6 7               5                                                        }
  647. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  648. {        |0 1 0| subop.| run length      |                                                        }
  649. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  650. {        |  3  |<- 4 ->|<-- 9 bits ----->|                                                        }
  651. {                                                                                                 }
  652. { ! Note that the stored run length is the actual value minus 1, but the macros deal with the    }
  653. { ! actual value!                                                                                }
  654.     kPEFRelocRunMaxRunLength    = 512;
  655.  
  656.  
  657. { =========================================================================================== }
  658. { RelocSmIndex Group }
  659. { ------------------ }
  660.  
  661. { ----------------------------------------------------------------------------------------    }
  662. { The "RelocSmIndex" group includes the "RelocSmByImport", "RelocSmSetSectC",                }
  663. { "RelocSmSetSectD" and "RelocSmBySection" instructions.  This group has the following bit    }
  664. { field layout.                                                                            }
  665. {                                                                                             }
  666. {                                       1                                                    }
  667. {         0   2 3     6 7               5                                                    }
  668. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    }
  669. {        |0 1 1| subop.| index           |                                                    }
  670. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                    }
  671. {        |  3  |<- 4 ->|<-- 9 bits ----->|                                                    }
  672. {                                                                                             }
  673. { ! Note that the stored index is the actual value!                                        }
  674.     kPEFRelocSmIndexMaxIndex    = 511;
  675.  
  676.  
  677. { =========================================================================================== }
  678. { RelocIncrPosition Instruction }
  679. { ----------------------------- }
  680.  
  681. { -------------------------------------------------------------------------------------------    }
  682. { The "RelocIncrPosition" instruction has the following bit field layout.                        }
  683. {                                                                                                 }
  684. {                                       1                                                        }
  685. {         0     3 4                     5                                                        }
  686. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  687. {        |1 0 0 0| offset                |                                                        }
  688. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  689. {        |<- 4 ->|<-- 12 bits ---------->|                                                        }
  690. {                                                                                                 }
  691. { ! Note that the stored offset is the actual value minus 1, but the macros deal with the        }
  692. { ! actual value!                                                                                }
  693.     kPEFRelocIncrPositionMaxOffset = 4096;
  694.  
  695.  
  696. { =========================================================================================== }
  697. { RelocSmRepeat Instruction }
  698. { ------------------------- }
  699.  
  700. { -------------------------------------------------------------------------------------------    }
  701. { The "RelocSmRepeat" instruction has the following bit field layout.                            }
  702. {                                                                                                 }
  703. {                                       1                                                        }
  704. {         0     3 4     7 8             5                                                        }
  705. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  706. {        |1 0 0 1| chnks | repeat count  |                                                        }
  707. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                                        }
  708. {        |<- 4 ->|<- 4 ->|<-- 8 bits --->|                                                        }
  709. {                                                                                                 }
  710. { ! Note that the stored chunk count and repeat count are the actual values minus 1, but the    }
  711. { ! macros deal with the actual values!                                                        }
  712.     kPEFRelocSmRepeatMaxChunkCount = 16;
  713.     kPEFRelocSmRepeatMaxRepeatCount = 256;
  714.  
  715.  
  716. { =========================================================================================== }
  717. { RelocSetPosition Instruction }
  718. { ---------------------------- }
  719.  
  720. { -------------------------------------------------------------------------------------------    }
  721. { The "RelocSetPosition" instruction has the following bit field layout.                        }
  722. {                                                                                                 }
  723. {                                       1                                   1                    }
  724. {         0         5 6                 5     0                             5                    }
  725. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  726. {        |1 0 1 0 0 0| offset (high)     |   | offset (low)                  |                    }
  727. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  728. {        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    }
  729. {                                                                                                 }
  730. { ! Note that the stored offset is the actual value!                                            }
  731.     kPEFRelocSetPosMaxOffset    = $03FFFFFF;                    {  67,108,863  }
  732.  
  733.  
  734. { =========================================================================================== }
  735. { RelocLgByImport Instruction }
  736. { --------------------------- }
  737.  
  738. { -------------------------------------------------------------------------------------------    }
  739. { The "RelocLgByImport" instruction has the following bit field layout.                        }
  740. {                                                                                                 }
  741. {                                       1                                   1                    }
  742. {         0         5 6                 5     0                             5                    }
  743. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  744. {        |1 0 1 0 0 1| index (high)      |   | index (low)                   |                    }
  745. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  746. {        |<-- 6 ---->|<-- 10 bits ------>|   |<-- 16 bits ------------------>|                    }
  747. {                                                                                                 }
  748. { ! Note that the stored offset is the actual value!                                            }
  749.     kPEFRelocLgByImportMaxIndex    = $03FFFFFF;                    {  67,108,863  }
  750.  
  751.  
  752. { =========================================================================================== }
  753. { RelocLgRepeat Instruction }
  754. { ------------------------- }
  755.  
  756. { -------------------------------------------------------------------------------------------    }
  757. { The "RelocLgRepeat" instruction has the following bit field layout.                            }
  758. {                                                                                                 }
  759. {                             1         1                                   1                    }
  760. {         0         5 6     9 0         5     0                             5                    }
  761. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  762. {        |1 0 1 1 0 0| chnks | rpt (high)|   | repeat count (low)            |                    }
  763. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  764. {        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    }
  765. {                                                                                                 }
  766. { ! Note that the stored chunk count is the actual value minus 1, but the macros deal with        }
  767. { ! the actual value!  The stored repeat count is the actual value!                            }
  768.     kPEFRelocLgRepeatMaxChunkCount = 16;
  769.     kPEFRelocLgRepeatMaxRepeatCount = $003FFFFF;                {  4,194,303  }
  770.  
  771.  
  772. { =========================================================================================== }
  773. { RelocLgSetOrBySection Group }
  774. { --------------------------- }
  775.  
  776. { -------------------------------------------------------------------------------------------    }
  777. { The "RelocLgSetOrBySection" instruction is really a group including the "RelocLgBySection",    }
  778. { "RelocLgSetSectC" and "RelocLgSetSectD" instructions.  This group has the following bit        }
  779. { field layout.                                                                                }
  780. {                                                                                                 }
  781. {                             1         1                                   1                    }
  782. {         0         5 6     9 0         5     0                             5                    }
  783. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  784. {        |1 0 1 1 0 1| subop | idx (high)|   | index (low)                   |                    }
  785. {        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    }
  786. {        |<--  6 --->|<- 4 ->|<--  6 --->|   |<-- 16 bits ------------------>|                    }
  787. {                                                                                                 }
  788. { ! Note that the stored index is the actual value!                                            }
  789.     kPEFRelocLgSetOrBySectionMaxIndex = $003FFFFF;                {  4,194,303  }
  790.  
  791.  
  792.  
  793. {$ALIGN RESET}
  794. {$POP}
  795.  
  796. {$SETC UsingIncludes := PEFBinaryFormatIncludes}
  797.  
  798. {$ENDC} {__PEFBINARYFORMAT__}
  799.  
  800. {$IFC NOT UsingIncludes}
  801.  END.
  802. {$ENDC}
  803.